package com.hisense.ovcloud.asop.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.hisense.ovcloud.asop.clients.BasicDataClient;
import com.hisense.ovcloud.asop.config.Constants;
import com.hisense.ovcloud.asop.dto.req.ServiceMetricBizReq;
import com.hisense.ovcloud.asop.dto.resp.ASOPBaseResp;
import com.hisense.ovcloud.asop.dto.resp.ServiceLogMetricResp;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerRequest;
import reactor.core.publisher.Mono;

import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

/**
 * @author: yangweiping1
 * @description:
 * @date: 2025/3/27 13:45
 */
@Service
public class ServiceLogService {

    public Mono<ASOPBaseResp> queryMetricBizLog(ServerRequest req) {
        return basicDataClient.verifyToken(req)
                .zipWhen(checkTokenResp -> {
                    if (checkTokenResp.isExist()) {
                        return req.bodyToMono(ServiceMetricBizReq.class).flatMap(r -> {
                            ServiceMetricBizReq newReq = defaultParam(r);
                            return this.queryMetricBizLog(newReq)
                                    .zipWhen(result -> {
                                        if (result == null || result.isEmpty()) {
                                            return Mono.just(ASOPBaseResp.builder()
                                                    .data(Lists.newArrayList())
                                                    .pageNum(newReq.getPageNum())
                                                    .pageSize(newReq.getPageSize())
                                                    .total(0).build());
                                        } else {
                                            return Mono.just(ASOPBaseResp.builder()
                                                    .data(Lists.partition(result, newReq.getPageSize()).get(newReq.getPageNum() - 1))
                                                    .pageNum(newReq.getPageNum())
                                                    .pageSize(newReq.getPageSize())
                                                    .total(result.size()).build());
                                        }
                                    }, (x, y) -> y);
                        });
                    } else {
                        return Mono.just(ASOPBaseResp.builder()
                                .data(new ArrayList<>())
                                .resultCode(Constants.INVALID_TOKEN)
                                .errorMsg(Constants.ERRORS.BAD_TOKEN)
                                .build());
                    }
                }, (x, y) -> y);
    }

    private ServiceMetricBizReq defaultParam(ServiceMetricBizReq req) {
        // 默认值
        if (req.getQueryType() == null) {
            req.setQueryType(2);
        }

        if (req.getPageSize() == null) {
            req.setPageSize(20);
        }

        if (req.getPageNum() == null) {
            req.setPageNum(1);
        }

        if (req.getStartTime() == null) {
            req.setStartTime(System.currentTimeMillis() - 24 * 3600 * 1000);
        }

        if (req.getEndTime() == null) {
            req.setEndTime(System.currentTimeMillis());
        }
        return req;
    }


    private Mono<List<ServiceLogMetricResp>> queryMetricBizLog(ServiceMetricBizReq req) {
        if (req.getQueryType() == 2) {
            String startTime = formatUTCDate(req.getStartTime());
            String endTime = formatUTCDate(req.getEndTime());
            long duration = (req.getEndTime() - req.getStartTime()) / 1000; // 计算持续时间（秒）
            return chServiceLogQueryService.queryMetricBizLog(startTime, endTime, duration, req.getService(), req.getPath(), req.getField(), req.getOrder());
        } else {
            throw new RuntimeException("查询类型错误");
        }
    }

    private final BasicDataClient basicDataClient;

    private final CHServiceLogQueryService chServiceLogQueryService;

    public ServiceLogService(BasicDataClient basicDataClient, CHServiceLogQueryService chServiceLogQueryService) {
        this.basicDataClient = basicDataClient;
        this.chServiceLogQueryService = chServiceLogQueryService;
    }

    public static String formatUTCDate(long timestamp) {
        DateTime date = DateUtil.date(timestamp).setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
        return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
    }
}
